package cn.com.fstar.core.log;

import cn.com.fstar.core.pageModel.User;
import cn.com.fstar.core.util.UserUtil;
import cn.com.fstar.framework.base.dao.BaseDaoImpl;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * aop 实现日志记录（包括错误日志）
 * Created by lim on 2017/9/4.
 */
@Component
@Aspect
public class SystemLogAspect {

    private Logger logger = Logger.getLogger(SystemLogAspect.class);

    @Autowired
    private BaseDaoImpl<SystemLog> baseDao;

    @Pointcut("@annotation(SystemLogMessage))")
    public void pointcut() {}

    @Before("pointcut()")
    public void beforeWithAnnotaion(JoinPoint joinPoint){
        try {
            System.out.println("-----system log ...-----");
            baseDao.save(setSystemLog(joinPoint,0));
        } catch (Exception e) {
            logger.error(ExceptionUtils.getStackTrace(e));
        }
    }

    @AfterThrowing(value = "pointcut()", throwing = "e")
    public void beforeWithAnnotaion(JoinPoint joinPoint, Exception e){
        try {
            SystemLog systemLog = setSystemLog(joinPoint,1);
            systemLog.setExceptionCode(e.getClass().getName());
            systemLog.setExceptionDetail(ExceptionUtils.getStackTrace(e));
            baseDao.save(systemLog);
        } catch (Exception e1) {
            logger.error(ExceptionUtils.getStackTrace(e1));
        }
    }

    public SystemLog setSystemLog(JoinPoint joinPoint, int type) throws Exception{
        SystemLog systemLog = new SystemLog();
        User user;
        if(null != RequestContextHolder.getRequestAttributes()){
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            systemLog.setRequestIp(request.getRemoteAddr());
            HttpSession session = request.getSession();
            user = (User)session.getAttribute(UserUtil.LOGIN_USER);
            if(null != user)
                systemLog.setUserId(user.getLoginName()+"（"+user.getUserName()+"）");
        }

        //获取用户请求方法的参数并序列化为JSON格式字符串
        System.out.println("----"+joinPoint.getArgs());
//        ActionContext ctx = (ActionContext)joinPoint.getArgs()[0];
//        systemLog.setParams(JSONObject.toJSONString(ctx.ajaxParams()));
        systemLog.setType(type);
        systemLog.setDescription(getAnnotaionDescription(joinPoint));
        systemLog.setMethod(joinPoint.getTarget().getClass().getSimpleName()+"/"+joinPoint.getSignature().getName());
        if(systemLog.getDescription().equals("")) systemLog.setDescription(joinPoint.getSignature().getName());
        systemLog.setLogTime(new Date());

        return systemLog;
    }

    public String getAnnotaionDescription(JoinPoint joinPoint) throws Exception{
        String methodName = joinPoint.getSignature().getName();
        Class targetClass = joinPoint.getTarget().getClass();
        Method[] methods = targetClass.getMethods();
        Object[] arguments = joinPoint.getArgs();
        String description = "";
        for(Method method: methods){
            if(!method.getName().equals(methodName)) continue;
            Class[] clazzs = method.getParameterTypes();
            if(clazzs.length != arguments.length) continue;
            SystemLogMessage s = method.getAnnotation(SystemLogMessage.class);
            if(null == s) description = methodName;
            else description = s.value();
        }
        return description;
    }

}
